# 用户账户相关功能：注册， 短信， 登陆， 注销
from django.shortcuts import render, HttpResponse, redirect
from django import forms
from django.core.validators import RegexValidator
import re
from web import models
from s28 import settings
from utrl.centent import sms
import random
from django_redis import get_redis_connection
from django.http import JsonResponse
import json
from django.core.exceptions import ValidationError
import io
from scripts.init_price_police import S28
import time
import datetime
from utrl.centent.alipay import AliPay
from django.conf import settings
from web.forms.register_login import *



# 这个注册页面的get请求和post请求
def register(request):
    if request.method == 'GET':
        fors = RegisTerS()
        return render(request, 'register.html', {'fors': fors})
    fors = RegisTerS(request.POST)
    print('fors')
    if fors.is_valid():
        print('已经通过了is——valid')
        # 验证通过 就把用户的信息写入数据库
        name = fors.cleaned_data.get('name')
        pwd = fors.cleaned_data.get('pwd')
        mobile_phone = fors.cleaned_data.get('mobile_phone')
        # 将用户的信息写入用户信息表里
        S28().insert_into('user_information', {'user': name, 'password': pwd, 'mobile_phone':mobile_phone})
        # 查询当前用户的id
        user_id = S28().select_one('id', 'user_information', 'user', str(name))
        new = time.time()+28800
        array1 = time.gmtime(new)
        dt = time.strftime('%Y-%m-%d %H:%M:%S', array1)
        # 创建一条交易记录
        S28().insert_into('user_as_vip', {'as_buy': '已支付', 'user_id': str(user_id), 'price_id': '1', 'buy': '0', 'start_time': str(dt), 'year_order': '999'})
        return JsonResponse({'status': True, 'data': '/index/'})
    # 验证不通过 就返回页面和错误信息
    return JsonResponse({'status': False, 'error': fors.errors})
##################################################################################################
# 验证短信类



# 短信注册
def send_sms(request):
    """发送短信"""

    form = SendSmsForm(request, data=request.GET)

    # 只是校验手机号：不能为空、格式是否正确
    if form.is_valid():
        return JsonResponse({'status': True})

    return JsonResponse({'status': False, 'error': form.errors})

##################————————————————————————————##########################################


def login_sms(request):
    if request.method == 'GET':
        form = LoginSmsFrom()
        return render(request, 'login_sms.html', {'form': form})
    if request.method == 'POST':
        form = LoginSmsFrom(request.POST)
        print(request.POST)
        if form.is_valid():
            print('用户登录成功')
            mobile_phone = form.cleaned_data['mobile_phone']
            print('把用户写入到session中')
            user = S28().search('user_information', {'mobile_phone': mobile_phone})
            request.session['user_id'] = user[0][0]
            return JsonResponse({"status": True, 'data': "/index/"})
        return JsonResponse({"status": False, 'error': form.errors})



#######################-------###################################################################



def login(request):
    """用户名和密码登陆"""
    if request.method == 'GET':
        form = LoginForm(request)
        return render(request, 'login.html', {'form': form})

    errors = {}
    form = LoginForm(request, data=request.POST)
    if form.is_valid():
        user_name = form.cleaned_data.get('user')     # 获取输入的账号
        password = form.cleaned_data.get('password')  # 获取输入的密码
        ret = re.search('1[3|5|7|9]\d{9}', str(user_name))  # 正则匹配
        if ret == None:
            user_data = S28().search('user_information', {'user': user_name})
            if len(user_data) != 0:
                user_data_password = user_data[0][2]
                if password == str(password):
                    request.session['user_id'] = user_data[0][0]
                    request.session.set_expiry(60 * 60 * 24 * 14)
                    return redirect('/index/')
                else:
                    errors['pwd'] = '密码错误'
            else:
                errors['name'] = '账号不存在'
        else:
            user_data = S28().search('user_information', {'mobile_phone': user_name})
            if len(user_data) != 0:
                user_data_password = user_data[0][2]
                if user_data_password == str(password):
                    request.session['user_id'] = user_data[0][0]
                    request.session.set_expiry(60 * 60 * 24 * 14)
                    return redirect('/index/')
                else:
                    errors['pwd'] = '密码错误'
            else:
                errors['name'] = '账号不存在'
    return render(request, 'login.html', {'form': form, 'error': errors})

def image_code(request):
    """生成图片的验证码"""
    from io import BytesIO
    from utrl.img_code import check_code
    image_object, code = check_code()
    stream = BytesIO()
    image_object.save(stream, 'png')
    request.session['image_code'] = code
    request.session.set_expiry(60)  # 主动修改session的过期时间
    s = stream.getvalue()


    return HttpResponse(s)


# 退出
def logout(request):
    request.session.flush()
    return redirect('index')




# 套餐

def price(request):
    vip_list = S28().py_searche('select * from vip where id>=2')
    return render(request, 'price.html', {'vip_list': vip_list})


def payment(request, vip_id):
    vip = S28().search('vip', {'id':vip_id})
    # 如果传过来的参数是不正确的
    if len(vip) == 0:
        return redirect('price')
    # 如果购买的数量不是一个十进制的数字
    number = request.GET.get('number', '')
    if not number or not number.isdecimal():
        return redirect('price')

    number = int(number)
    if number < 1:
        return redirect('price')
    # 这个是原价
    origin_price = number * int(vip[0][3])

    # 这个是查看当前用户是否有买过vip的记录
    old_vip = S28().search('user_as_vip', {'user_id': request.user_id})
    # 结束的时间减去当前的时间／365 *价格
    actual_payment = origin_price   # 抵扣后的实际价格
    discount = 0  # 可以抵扣的金额
    # 原来的订单信息
    _object = None
    if len(old_vip)>1:
        ret = old_vip
        old_pay = ret[1]
        days = old_pay[6] - datetime.datetime.now()
        discount = float('%.2f' % (days.days / 365 * old_pay[4]))
        actual_payment = origin_price - discount
        _object = old_pay

    content = {
        'vip_id': vip_id,  # 套餐的id
        'number': number,  # 套餐的数量
        'origin_price':origin_price, # 套餐的原价
        'discount': discount,  # 原来的套餐可以抵扣价格
        'actual_payment': actual_payment  # 抵扣后的实际价格
    }
    conn = get_redis_connection()
    key = 'payment_{}'.format(S28().search('user_information', {'id': request.user_id})[0][3])

    conn.set(key, json.dumps(content), ex=60*30)
    content['vip'] = vip
    content['object'] = _object
    return render(request, 'payment.html',  {'content': content})

"""
def pay(request):
    conn = get_redis_connection()
    key = 'payment_{0}'.format(S28().search('user_information', {'id': request.user_id})[0][3])
    content_string = conn.get(key)
    if not content_string:
        return redirect('price')
    content = json.loads(content_string.decode('utf-8'))
    print(content, '--------!!!我从redis里面取出来了数据')
    # 生成订单 （代付款）写入数据库中
    S28().insert_into('user_as_vip',{
        'as_buy': '未支付',
        'user_id': request.user_id,
        'price_id': content['vip_id'],
        'buy': content['actual_payment'],
        'year_order': content['number']
    })
    # 跳转支付宝的支付链接
    buy_num = content['actual_payment']

    parents = {
        'app_id': '2016103000777767',
        'method': 'alipay.trade.page.pay',
        'format': 'JSON',
        'return_url': 'http://127.0.0.1:8000/price/',
        'notify_url': 'http://127.0.0.1:8000/notify/',
        'charset': 'utf-8',
        'sign_type': 'RSA2',
        'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        'version': '1.0',
        'biz_content': json.dumps({
            'out_trade_no': key+'{}'.format(int(time.time())),
            'product_code': 'FAST_INSTANT_TRADE_PAY',
            'total_amount': buy_num,
            'subject': 'tracer2',
        }, separators=(',',':'))
    }  # 这里 'sign': '签名', 这个没有加
    # 获取待签名的字符串
    unsigned_string = '&'.join(["{0}={1}".format(k, parents[k]) for k in sorted(parents)])
    from Crypto.PublicKey import RSA
    from Crypto.Signature import PKCS1_v1_5
    from Crypto.Hash import SHA256
    from base64 import decodebytes, encodebytes
    # SHA256WithRSA + 应用私钥 对待签名的字符串 进行签名
    private_key = RSA.import_key(open('s28/files/应用私钥2048.txt').read())
    signer = PKCS1_v1_5.new(private_key)
    signature = signer.sign(SHA256.new(unsigned_string.encode('utf-8')))
    # 对签名之后的执行进行base64 编码  转化为字符串
    sign_string = encodebytes(signature).decode('utf-8').replace('\n','')
    # 把生成的签名赋值给sign参数，拼接到请求参数中
    from urllib.parse import quote_plus
    result = '&'.join(["{0}={1}".format(k,quote_plus(parents[k])) for k in sorted(parents)])
    result = result + '&sign='+ quote_plus(sign_string)
    gateway = 'https://openapi.alipaydev.com/gateway.do'
    ali_pay_url = '{0}?{1}'.format(gateway, result)

    return redirect(ali_pay_url)
"""

def pay(request):
    conn = get_redis_connection()
    key = 'payment_{0}'.format(S28().search('user_information', {'id': request.user_id})[0][3])
    content_string = conn.get(key)
    if not content_string:
        return redirect('price')
    content = json.loads(content_string.decode('utf-8'))
    print(content, '--------!!!我从redis里面取出来了数据')
    # 生成订单 （代付款）写入数据库中
    S28().insert_into('user_as_vip',{
        'as_buy': '未支付',
        'user_id': request.user_id,
        'price_id': content['vip_id'],
        'buy': content['actual_payment'],
        'year_order': content['number']
    })
    # 跳转支付宝的支付链接
    price = content['actual_payment']
    alipay = AliPay(
        appid=settings.ALI_APPID,
        app_notify_url=settings.ALI_NOTIFY_URL,
        return_url= settings.ALI_RETURN_URL,
        app_private_key_path=settings.ALI_PRI_KEY_PATH,
        alipay_public_key_path=settings.ALI_PUB_KEY_PATH
    )
    query_params = alipay.direct_pay(
        subject='TRACER会员',
        out_trade_no= key+'{}'.format(int(time.time())),
        total_amount= price

    )
    pay_url = "{}?{}".format(settings.ALI_GETEWAY,query_params)
    return redirect(pay_url)


def pay_notify(request):
    """支付成功后触发url"""
    alipay = AliPay(
        appid=settings.ALI_APPID,
        app_notify_url=settings.ALI_NOTIFY_URL,
        return_url=settings.ALI_RETURN_URL,
        app_private_key_path=settings.ALI_PRI_KEY_PATH,
        alipay_public_key_path=settings.ALI_PUB_KEY_PATH
    )
    if request.method == 'GET':
        # 制作跳转 判断是否支付成功
        # 支付宝返回订单号：获取订单id 然后格局订单id做状态更新 + 认证
        # 支付宝公钥对支付给我返回的数据request.GET 进行检查 检查通过才表示这个是支付宝返还的接口
        params = request.GET.dict()
        sign = params.pop('sign', None)
        status = alipay.verify(params, sign)
        print('GET认证',status, sign)
        return HttpResponse('支付成功')


    return HttpResponse('666')




def loaded(request):
    return JsonResponse({'status': True, 'data':'我发过去了'})